<?php

class OpinionService extends AbstractService
{

    protected function _init()
    {
	$this->setMapper(new OpinionMapper());
    }

    public function encode($url)
    {
	return md5($url);
    }

    public function getOpinionList($params = array(), $dependencyTag = null)
    {
	$cacheSlot = new CacheSlotsOpinionList($params, 0, new TagsDependency('all.opinion', $dependencyTag));
	if (($data = $cacheSlot->load()) === false) {
	    $data = $this->getMapper()->getOpinionList($params);
	    $cacheSlot->setData($data)->save();
	}
	return $data;
    }

    public function getLastPositiveOpinions($page = 1, $limit = 10)
    {
	$params = array(
	    'where' => 'o.user_rating >= 3',
	    'order' => 'o.id DESC',
	    'limit' => $limit,
	    'offset' => ($page - 1) * $limit
	);
	$opinions = $this->getOpinionList($params, 'positive.opinion');
	if ($opinions) {
	    foreach ($opinions as $opinion) {
		$opinion->setTarget(FactoryService::get($opinion->getDbData('target_type'))->get($opinion->getDbData('target_id')));
	    }
	}
	return $opinions;
    }

    public function getLastNegativeOpinions($page = 1, $limit = 10)
    {
	$params = array(
	    'where' => 'o.user_rating < 3',
	    'order' => 'o.id DESC',
	    'limit' => $limit,
	    'offset' => ($page - 1) * $limit
	);
	$opinions = $this->getOpinionList($params, 'negative.opinion');
	if ($opinions) {
	    foreach ($opinions as $opinion) {
		$opinion->setTarget(FactoryService::get($opinion->getDbData('target_type'))->get($opinion->getDbData('target_id')));
	    }
	}
	return $opinions;
    }

    public function onBeforeSave(AbstractModel $model = null)
    {
	if (parent::onBeforeSave($model)) {
	    if (!$model->getId()) {
		Rating::opinion($model);
	    }
	}
	return true;
    }

    public function onAfterSave(AbstractModel $model = null)
    {
	if ($model && $model->getDbData('target_id')) {
	    $targetModel = FactoryService::get($model->getDbData('target_type'))->get($model->getDbData('target_id'));
	    if ($targetModel) {
		$cacheSlotClass = 'CacheSlots' . ucfirst($model->getDbData('target_type')) . 'Features';
		if (!class_exists($cacheSlotClass)) {
		    throw new Exception('Cache slot class not defined');
		}
		$cacheSlot = new $cacheSlotClass($targetModel, 'opinions');
		$cacheSlot->delete();
		if ($model->getId()) {
		    FactoryService::get('search')->toIndex(array(
			'id' => 'opinion' . $model->getId(),
			'type' => 'opinion',
			'url' => Yii::app()->createUrl($model->getDbData('target_type') . '/view', array('id' => $targetModel->getId(), 'url' => $targetModel->getDbData('url'))),
			'text' => $model->getDbData('content'),
			'title' => $targetModel->getDbData('title')
		    ));
		}
	    }
	}
	if ($model->getId()) {
	    $cacheSlot = new CacheSlotsPk($this->getMapper()->getTableName(), $model->getId());
	    $cacheSlot->delete();
	}
	$opinionClearTag = $model->getDbData('user_rating') >= 3 ? 'positive.opinion' : 'negative.opinion';
	CacheManager::getCache('memcache')->clear($opinionClearTag);
	return true;
    }

    public function getExtendedData(OpinionModel $model)
    {
	if (!$model->getId()) {
	    return false;
	}
	FactoryService::get('image')->getByOpinion($model);
	FactoryService::get('map')->getByOpinion($model);
	FactoryService::get('video')->getByOpinion($model);
	$this->getOpinionUser($model);
    }

    public function getOpinionPositiveCount()
    {
	return $this->getCount(array("where" => "user_rating >= 3"));
    }

    public function getOpinionNegativeCount()
    {
	return $this->getCount(array("where" => "user_rating < 3"));
    }

    public function getCountByUser(UserModel $model)
    {
	if (!$model->getId()) {
	    return false;
	}
	return $this->getCount(array('where' => 'user_id = :user_id', 'params' => array(':user_id' => $model->getId())));
    }

    public function getOpinionUser(OpinionModel $model)
    {
	$userId = $model->getDbData('user_id');

	if (!$userId) {
	    return false;
	}


	$user = FactoryService::get('user')->get($userId);

	if ($user->getId()) {
	    $model->setUser($user);
	}
    }

    public function getByReview(ReviewModel $model)
    {
	if (!$model->getId()) {
	    return false;
	}

	$cacheSlot = new CacheSlotsReviewFeatures($model, 'opinions');
	if (($opinions = $cacheSlot->load()) === false) {
	    $opinions = $this->getMapper()->getByReviewId($model->getId());
	    if (!$opinions) {
		$opinions = array();
	    }
	    $cacheSlot->setData($opinions)->save();
	}
	$model->setOpinions($opinions);
    }

    public function getByCompany(CompanyModel $model)
    {
	if (!$model->getId()) {
	    return false;
	}

	$cacheSlot = new CacheSlotsCompanyFeatures($model, 'opinions');
	if (($opinions = $cacheSlot->load()) === false) {
	    $opinions = $this->getMapper()->getByCompanyId($model->getId());
	    $cacheSlot->setData($opinions)->save();
	}

	if (!$opinions) {
	    $opinions = array();
	}
	$model->setOpinions($opinions);
    }

    public function getByUser(UserModel $model, $page = 1, $limit = 10)
    {
	if (!$model->getId()) {
	    return false;
	}

//	$cacheSlot = new CacheSlotsUserFeatures($model, 'opinions', array('page' => $page, 'limit' => $limit));
//	if (($opinions = $cacheSlot->load()) === false) {
//	    $opinions = $this->getMapper()->getByUserId($model->getId(), $page, $limit);
//	    foreach ($opinions as $opinion) {
//		$targetModel = FactoryService::get($opinion->getDbData('target_type'))->get($opinion->getDbData('target_id'));
//		$opinion->setTarget($targetModel);
//	    }
//	    $cacheSlot->setData($opinions)->save();
//	}
	$opinions = $this->getMapper()->getByUserId($model->getId(), $page, $limit);
	foreach ($opinions as $opinion) {
	    $targetModel = FactoryService::get($opinion->getDbData('target_type'))->get($opinion->getDbData('target_id'));
	    $opinion->setTarget($targetModel);
	}
	$model->setOpinions($opinions);
    }

}